package com.uidp.ui;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.component.UISelectItems;
import javax.faces.component.html.HtmlPanelGrid;
import javax.faces.component.html.HtmlPanelGroup;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;

import com.acsior.ddfn.domain.MetaMatcher;
import com.acsior.sbc.exception.BusinessException;
import com.acsior.sbc.exception.SearchException;
import com.acsior.wu.bean.MBGeneral;
import com.acsior.wu.bean.utils.MBManager;
import com.uidp.domain.AttributeData;
import com.uidp.domain.Attributes;
import com.uidp.domain.Modul;
import com.uidp.domain.ModulElements;
import com.uidp.domain.ModulModulElements;
import com.uidp.uitils.ISelectItemAttribute;
import com.uidp.uitils.JSFComponentsBuilder;
import com.uidp.uitils.ManagedBeans;
import com.uidp.uitils.NavOutcomes;

public class MBBuildModul extends MBGeneral {

	/** грид, в който ще се билдват динамичните компоненти */
	private HtmlPanelGrid container;

	private Modul modul;
	private List<ModulModulElements> modulMElements;

	private List<AttributeData> attributesData;

	public MBBuildModul() {
		super();
		this.attributesData = new ArrayList<AttributeData>();
		try {
			this.modulMElements = ModulModulElements
					.searchModulElements(getModul());
			for (ModulModulElements m : getModulMElements()) {
				m.getModulElements().setAttributeses(
						Attributes.searchAttributes(m.getModulElements()));
			}
		} catch (BusinessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SearchException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.container = JSFComponentsBuilder.buildHPanelGrid(FacesContext
				.getCurrentInstance().getApplication(), null, null, 1);
		loadPanelGrid();

	}

	/**
	 * Изграждане на панел с динамични компоненти
	 */
	private void loadPanelGrid() {
		for (ModulModulElements m : getModulMElements()) {

			buildGroup(m.getModulElements());
			// създавам грид, в който ще построявам атрибути
			HtmlPanelGrid grid = JSFComponentsBuilder.buildHPanelGrid(
					FacesContext.getCurrentInstance().getApplication(), null,
					"pnlAttributes" + m.getModulElements().getElementname(), 2);

			getContainer().getChildren().add(grid);
			for (Attributes a : m.getModulElements().getAttributeses()) {
				try {
					AttributeData d = new AttributeData();
					d.setAttributes(a);
					attributesData.add(d);
					buildAttrribute(d, grid);
				} catch (BusinessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}

		}

	}

	/**
	 * @see MBGeneral#getManagedProp()
	 */
	protected ManagedBeans getManagedProp() {
		return ManagedBeans.buildModul;
	}

	public HtmlPanelGrid getContainer() {
		return container;
	}

	public void setContainer(HtmlPanelGrid container) {
		this.container = container;
	}

	public Modul getModul() {
		return modul;
	}

	public void setModul(Modul modul) {
		this.modul = modul;
	}

	public List<ModulModulElements> getModulMElements() {
		return modulMElements;
	}

	public void setModulMElements(List<ModulModulElements> modulMElements) {
		this.modulMElements = modulMElements;
	}

	/**
	 * 
	 * @param attr
	 */
	private void buildAttrribute(AttributeData attr, UIComponent component) {
		if (attr.getAttributes().getAttributeType().getLabel()
				.equals("selectItem")) {
			buildCheckboxComponent(attr, component);

		} else if (attr.getAttributes().getAttributeType().getLabel()
				.equals("inputDate")) {
			buildDateComponent(attr, component);

		} else if (attr.getAttributes().getAttributeType().getLabel()
				.equals("selectListItem")) {
			buildDropdownComponent(attr, component);

		} else if (attr.getAttributes().getAttributeType().getLabel()
				.equals("inputText")) {
			buildStringComponent(attr, component);
		}
	}

	/**
	 * @param group
	 */
	private void buildGroup(ModulElements group) {
		// разделител
		getContainer().getChildren().add(
				JSFComponentsBuilder.buildRichSeparator(FacesContext
						.getCurrentInstance().getApplication(), getContainer(),
						null, group.getElementname()));

		// име на раздел
		getContainer().getChildren().add(
				JSFComponentsBuilder.buildHOutputText(FacesContext
						.getCurrentInstance().getApplication(), getContainer(),
						null, group.getElementname(),
						JSFComponentsBuilder.STYLECLASS_BOLD));
	}

	/**
	 * 
	 * @param attr
	 * @param grid
	 */
	private void buildCheckboxComponent(AttributeData attr,
			UIComponent component) {
		// първа колона
		component.getChildren()
				.add(buildLabel(attr.getAttributes(), component));

		// втора колона
		if (attr.getAttributes().getIsRequired()) {
			HtmlPanelGroup group = JSFComponentsBuilder.buildHPanelGroup(
					FacesContext.getCurrentInstance().getApplication(),
					component, null);
			component.getChildren().add(group);
			group.getChildren().add(
					JSFComponentsBuilder.buildHSelectBooleanCheckbox(
							FacesContext.getCurrentInstance().getApplication(),
							group, null, attr.getAttributes()
									.getAttributeName(),
							buildValueExpresionByValue(attr, Boolean.class)));
			group.getChildren().add(buildRequired(group));

		} else {
			component.getChildren().add(
					JSFComponentsBuilder.buildHSelectBooleanCheckbox(
							FacesContext.getCurrentInstance().getApplication(),
							component, null, attr.getAttributes()
									.getAttributeName(),
							buildValueExpresionByValue(attr, Boolean.class)));
		}

	}

	/**
	 * 
	 * @param attr
	 * @param grid
	 */
	private void buildDateComponent(AttributeData attr, UIComponent component) {
		// първа колона
		component.getChildren()
				.add(buildLabel(attr.getAttributes(), component));

		// pattern Expresion за дата
		ValueExpression patternExpr = JSFComponentsBuilder
				.buildValueExpression(FacesContext.getCurrentInstance(),
						getManagedProp().getPropName(), "dateFormat",
						String.class);

		// втора колона
		if (attr.getAttributes().getIsRequired()) {
			HtmlPanelGroup group = JSFComponentsBuilder.buildHPanelGroup(
					FacesContext.getCurrentInstance().getApplication(),
					component, null);
			component.getChildren().add(group);

			group.getChildren().add(
					JSFComponentsBuilder.buildRichCalendar(FacesContext
							.getCurrentInstance().getApplication(), group,
							null, buildValueExpresionByValue(attr, Date.class),
							patternExpr));

			group.getChildren().add(buildRequired(group));

		} else {
			component.getChildren().add(
					JSFComponentsBuilder.buildRichCalendar(FacesContext
							.getCurrentInstance().getApplication(), component,
							null, buildValueExpresionByValue(attr, Date.class),
							patternExpr));
		}
	}

	/**
	 * 
	 * @param attr
	 * @param grid
	 */
	private void buildDropdownComponent(AttributeData attr,
			UIComponent component) {
		// // първа колона
		// component.getChildren().add(buildLabel(attr, component));
		//
		// // втора колона
		// if (attr.getRequired()) {
		// HtmlPanelGroup group = JSFComponentsBuilder.buildHPanelGroup(
		// FacesContext.getCurrentInstance().getApplication(),
		// component, null);
		// component.getChildren().add(group);
		// group.getChildren().add(
		// JSFComponentsBuilder.buildHSelectOneMenu(FacesContext
		// .getCurrentInstance().getApplication(), component,
		// null, getItems(attr),
		// buildValueExpresionByValue(attr, String.class)));
		// group.getChildren().add(buildRequired(group));
		//
		// } else {
		// component.getChildren().add(
		// JSFComponentsBuilder.buildHSelectOneMenu(FacesContext
		// .getCurrentInstance().getApplication(), component,
		// null, getItems(attr),
		// buildValueExpresionByValue(attr, String.class)));
		// }

	}

	/**
	 * 
	 * @param attr
	 * @param grid
	 */
	private void buildStringComponent(AttributeData attr, UIComponent component) {

		// първа колона
		component.getChildren()
				.add(buildLabel(attr.getAttributes(), component));

		// втора колона
		if (attr.getAttributes().getIsRequired()) {
			HtmlPanelGroup group = JSFComponentsBuilder.buildHPanelGroup(
					FacesContext.getCurrentInstance().getApplication(),
					component, null);
			component.getChildren().add(group);
			group.getChildren().add(
					JSFComponentsBuilder.buildHInputText(FacesContext
							.getCurrentInstance().getApplication(), group,
							null,
							buildValueExpresionByValue(attr, String.class)));
			group.getChildren().add(buildRequired(group));

		} else {
			component.getChildren().add(
					JSFComponentsBuilder.buildHInputText(FacesContext
							.getCurrentInstance().getApplication(), component,
							null,
							buildValueExpresionByValue(attr, String.class)));
		}

	}

	/**
	 * @param attr
	 * @param comp
	 * @return Лейбъл на компонента
	 */
	private UIComponent buildLabel(Attributes attr, UIComponent comp) {
		return JSFComponentsBuilder.buildHOutputText(FacesContext
				.getCurrentInstance().getApplication(), comp, null, attr
				.getAttributeName());
	}

	/**
	 * @param comp
	 * @return Компонент звездичка
	 */
	private UIComponent buildRequired(UIComponent comp) {
		return JSFComponentsBuilder.buildHOutputText(FacesContext
				.getCurrentInstance().getApplication(), comp, null, "*",
				JSFComponentsBuilder.STYLECLASS_ERROR_STYLE_BOLD);
	}

	/**
	 * @param attr
	 * @param expectedClass
	 * @return ValueExpression за атрибут на компонента "value"
	 */
	private ValueExpression buildValueExpresionByValue(AttributeData attr,
			Class<?> expectedClass) {
		return JSFComponentsBuilder.buildValueExpression(
				FacesContext.getCurrentInstance(), "modulHolder", "values['"
						+ attr.getAttributes().getUniqname() + "']",
				expectedClass);
	}

	@SuppressWarnings("unused")
	private UISelectItems getItems(Attributes attr) {
		UISelectItems items = new UISelectItems();
		// Collection<SelectItem> list = new ArrayList<SelectItem>();
		//
		// for (ISelectItemAttribute it : attr.getSelectItems()) {
		// list.add(new SelectItem(it.getSystemName(), it.getName()));
		// }
		//
		// items.setValue(list);
		return items;

	}

	public String saveData() {
		for (AttributeData m : getAttributesData()) {
			String val = getValues().get(m.getAttributes().getUniqname()) == null ? ""
					: getValues().get(m.getAttributes().getUniqname()).toString();
			m.setAttributeValue(val);
			m.setModul(getModul());
			try {
				m.store();
			} catch (BusinessException e) {

			}
		}
		return navigate(NavOutcomes.home);

	}

	public List<AttributeData> getAttributesData() {
		return attributesData;
	}

	public void setAttributesData(List<AttributeData> attributesData) {
		this.attributesData = attributesData;
	}

	/**
	 * @return the values
	 */
	public Map<String, Object> getValues() {
		return getMBModulHolder().getValues();
	}

	/**
	 * Извлича от FacesContext-а MBGroup
	 * 
	 * @return връща MBGroup
	 */
	protected MBModulHolder getMBModulHolder() {
		return (MBModulHolder) MBManager
				.findBeanInCtx(ManagedBeans.modulHolder);
	}

}
